<?php

	abstract class sm_parse{

		function constants($str, $mf=false, $ir=false){
			if(!$ir && !$mf){
				while(!is_null($rep = sm_constreplace($str, false, true))) $str = $rep;
				return $str;
			}
			$fail = $mf ? $str : null;
			if(($op = sm_strpos($str, '%{')) == -1) return $fail;
			if($mf && ($op != 0)) return $str;
			if(($cp = sm_strpos($str, '}')) == -1) return $fail;
			$cnst = substr($str, $op+2, $cp-$op-2);
			return defined($cnst) ? substr($str, 0, $op) . constant($cnst) . substr($str, $cp+1) : $fail;
		}
		
		function splitvars($str){
			$var = $cnt = $esc = false;
			$vars = $cnts = $strs = array();
			$cur = '';
			foreach(str_split($str) as $c){
				if(!preg_match('/[\w\d_]/', $c)){
					$was = $var;
					$cos = $cnt;
					$brk = ($var || $cnt);
					$var = $cnt = false;
					switch($c){
						case '\\':
							$esc = !$esc;
							if(!$esc) $cur = substr($cur, 0, -1);
							break;
						case '$':
							$brk = $var = !$esc;
							if(!$var) $cur = substr($cur, 0, -1);
							$esc = false;
							break;
						case '%':
							$brk = $cnt = !$esc;
							if(!$cnt) $cur = substr($cur, 0, -1);
							$esc = false;
							break;
						default:
							$esc = false;
					}
				}else $brk = $esc = false;
				if($brk && $cur){
					$vars[] = $was ? $cur : '';
					$cnts[] = $cos ? $cur : '';
					$strs[] = ($was || $cos) ? '' : $cur;
					$cur = '';
					$brk = false;
				}
				$cur .= $c;
			}
			if($cur){
				$vars[] = $var ? $cur : '';
				$cnts[] = $cnt ? $cur : '';
				$strs[] = ($var || $cnt) ? '' : $cur;
			}
			return array($vars, $cnts, $strs);
		}
		
		function vars($str, $A=false, $B=false){
			// we don't have this sorted yet
			if(!$A) $A = new obj;
			// ...
			list($vars, $cnts, $strs) = self::splitvars($str);
			//return print_r(array($vars, $cnts, $strs), 1);
			//foreach($strs as $i=>$v) $strs[$i] = sm_constreplace($v, 1);
			$str = '';
			foreach($vars as $i=>$v){
				if($v){
					if($k = substr($v, 1)){
						if($B && (isset($B->$k))) $v = $B->$k;
						else $v = $A->get($k);
					}
					$str .= $v;
					continue;
				}
				if($v = $cnts[$i]){
					if($k = substr($v, 1)) $v = defined($k) ? constant($k) : '';
					$str .= $v;
					continue;
				}
				$str .= $strs[$i];
			}
			return $str;
		}
		
		function ini_string($str, $process_sections=false){
			$p = 'inistrings/'.INSTANCE;
			Cache::write($p, $str);
			$ini = @parse_ini_file(Cache::pathto($p), $process_sections);
			Cache::delete($p);
			// don't return null
			return $ini ? $ini : false;
		}
	}


